package com.trytech.mongoocrawler.server.transport;

import com.trytech.mongoocrawler.common.bean.ClientInfo;
import com.trytech.mongoocrawler.common.bean.ConnectionManager;
import com.trytech.mongoocrawler.common.bean.MonitorData;
import com.trytech.mongoocrawler.common.transport.protocol.AbstractProtocol;
import com.trytech.mongoocrawler.common.transport.protocol.CrawlerTransferProtocol;
import com.trytech.mongoocrawler.common.transport.protocol.MonitorProtocol;
import com.trytech.mongoocrawler.common.transport.protocol.ProtocolFilterChain;
import com.trytech.mongoocrawler.server.CrawlerContext;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.InetSocketAddress;

/**
 * Created by coliza on 2018/5/24.
 */
public class CrawlerServerHandler extends AbstractNettyServerHandler {
    private ProtocolFilterChain filterChain;

    public CrawlerServerHandler(CrawlerContext crawlerContext, ProtocolFilterChain filterChain) {
        this.crawlerContext = crawlerContext;
        this.filterChain = filterChain;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, CrawlerTransferProtocol transferProtocol) throws Exception {
        Object obj = transferProtocol.getContent();
        AbstractProtocol protocol = filterChain.doFilter((AbstractProtocol) obj);
        ((MonitorProtocol) protocol).getMonitorData().getServerConfig();
        // 向客户端发送消息
        // 在当前场景下，发送的数据必须转换成ByteBuf数组
        transferProtocol = new CrawlerTransferProtocol();
        transferProtocol.setContent(protocol);
        transferProtocol.setType(protocol.getType().val());
        transferProtocol.setCls(protocol.getClass());
        ctx.writeAndFlush(transferProtocol).sync();
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        //当从客户端收到新的连接请求时，将客户端信息上报到监控端
        NioSocketChannel socketChannel = (NioSocketChannel) ctx.channel();
        InetSocketAddress insocket = (InetSocketAddress) socketChannel
                .remoteAddress();
        String clientIP = insocket.getAddress().getHostAddress();

        ClientInfo clientInfo = new ClientInfo(clientIP, socketChannel);
        ConnectionManager.registerConnection(clientInfo);
        MonitorData.getInstance().registerClient(clientInfo);

    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        //当客户端断开连接时，将客户端信息上报到监控端
        super.handlerRemoved(ctx);
        InetSocketAddress insocket = (InetSocketAddress) ctx.channel()
                .remoteAddress();
        String clientIP = insocket.getAddress().getHostAddress();
        ConnectionManager.removeConnection(clientIP);
        MonitorData.getInstance().removeClient(clientIP);
    }

}
